package com.person.yhzs.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.person.yhzs.common.Constants;
import com.person.yhzs.common.page.PageRequest;
import com.person.yhzs.common.page.PageResponse;
import com.person.yhzs.exception.BaseException;
import com.person.yhzs.exception.InvalidDataException;
import com.person.yhzs.user.entity.User;
import com.person.yhzs.user.entity.dto.LoginDto;
import com.person.yhzs.user.entity.dto.UserDto;
import com.person.yhzs.user.entity.vo.UserVo;
import com.person.yhzs.user.mapper.UserMapper;
import com.person.yhzs.user.service.UserService;
import com.person.yhzs.util.*;
import com.person.yhzs.wxPayV3.common.WechatConstants;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


/**
 * @author luolin
 * @version 1.0.0
 * @ClassName UserServiceImpl.java
 * @Description TODO
 * @createTime 2022年05月30日 14:36:00
 */
@Service
public class UserServiceImpl implements UserService {

    static final Logger LOGGER = LoggerFactory.getLogger(UserServiceImpl.class);

    @Autowired
    UserMapper userMapper;

    @Autowired
    RedisUtil redisUtil;

    @Resource
    WechatConstants wechatConstants;

    @Override
    public Map<String, Object> quickLogin(String phone) {
        User user = userMapper.checkUser(phone);
        LoginDto loginDto = new LoginDto();
        if(user == null){
            UserDto userDto = new UserDto();
            userDto.setUserPhone(phone);
            userDto.setUserPassword(phone.substring(phone.length()-6,phone.length()));
            LOGGER.warn(JSON.toJSONString(userDto));
            this.insertUser(userDto);
            loginDto.setAccount(phone);
            loginDto.setPassword(userDto.getUserPassword());
        }else{
            loginDto.setAccount(phone);
            loginDto.setPassword(user.getUserPassword());
        }
        return this.login(loginDto);
    }

    @Override
    public Map<String, Object> wxPhone(String code) {

        String appid = wechatConstants.getAPPID();
        String secret = wechatConstants.getSECRET();

        Map<String, Object> tokenMap = null;
        Map<String, Object> phoneMap = null;
        try {
            String token_url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, secret);
            String tokenMsgStr = HttpUtil.httpGet(token_url);
            if(StringUtils.isBlank(tokenMsgStr)){
                throw new BaseException("获取token错误！");
            }
            tokenMap = JsonUtil.readMap(tokenMsgStr);
            String access_token = (String) tokenMap.get("access_token");
            LOGGER.warn("获取Token信息：" + access_token);
            String url = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + access_token ;
            Map<String, String> paramMap = new HashMap<>();
            paramMap.put("code", code);
            String pm = JSON.toJSONString(paramMap);
            String phoneMsgStr = HttpUtil.httpPost(url,pm);
            if(StringUtils.isBlank(phoneMsgStr)){
                throw new BaseException("获取手机号错误！");
            }
            LOGGER.warn("手机号：" + phoneMsgStr);
            phoneMap = JsonUtil.readMap(phoneMsgStr);
        }catch (Exception e){
            new BaseException("登录请求失败！");
        }
        return phoneMap;
    }

    @Override
    public Map<String, Object> wxLogin(String code) {
        String appid = wechatConstants.getAPPID();
        String secret = wechatConstants.getSECRET();
        String grant_type = wechatConstants.getGRANT_TYPE();

        Map<Object, Object> param = new HashMap<>();
        param.put("appid", appid);
        param.put("secret",secret);
        param.put("js_code",code);
        param.put("grant_type",grant_type);
        Map<String, Object> objectMap = null;
        try {
            String s = HttpUtil.httpGet("https://api.weixin.qq.com/sns/jscode2session", param);
            if(StringUtils.isBlank(s)){
                throw new BaseException("获取openid错误！");
            }
            objectMap = JsonUtil.readMap(s);

            String openid = (String) objectMap.get("openid");
            String session_key = (String) objectMap.get("session_key");
        }catch (Exception e){
            new BaseException("登录请求失败！");
        }
        return objectMap;
    }

    @Override
    public Map<String, Object> login(LoginDto loginDto) {
        CommonUtil.checkObject(loginDto);
        if (StringUtils.isBlank(loginDto.getAccount()) || StringUtils.isBlank(loginDto.getPassword())) {
            throw new InvalidDataException("账号或密码不能为空");
        }
        User user = userMapper.getUser(loginDto.getAccount(), loginDto.getPassword());
        if (user == null) {
            throw new InvalidDataException("无效的用户名或密码");
        }
        if (user.getActive() == 0) {
            throw new BaseException("账户未激活");
        }
        UserDto userDto = new UserDto();
        userDto.setId(user.getId());
        userDto.setUserLoginTime(new Date());
        userMapper.updateUser(userDto);
        return generateToken(user);
    }

    /**
     * 生成用户token
     *
     * @param user
     * @return
     */
    private Map<String, Object> generateToken(User user) {
        Map<String, Object> map = new HashMap<>();
        String token = JwtUtil.generateUserToken(user, redisUtil);
        map.put("token", token);
        map.put("userInfo", user);
        return map;
    }

    @Override
    public void logout(Integer userId) {
//        LOGGER.info("接收到用户{}退出请求", userId);
        if (userId == null) {
            throw new BaseException("退出失败，无法识别用户");
        }
        String format = String.format(RedisUtil.KEY_USER_ID, userId);
        if (redisUtil.hasKey(format)) {
            redisUtil.del(format);
        }
    }

    @Transactional
    @Override
    public void insertUser(UserDto userDto) {
        User user = null;
        if(userDto.getUserDie() == Constants.BE_LIVING && StringUtils.isBlank(userDto.getUserPhone())){
            throw new BaseException("手机号不能为空！");
        }
        if(StringUtils.isNotBlank(userDto.getUserPhone())){
            user = userMapper.checkUser(userDto.getUserPhone());
            if(user != null){
                throw new BaseException("该手机号已被使用！");
            }
        }


        // 若在世，则设置密码
        if(userDto.getUserDie() == Constants.BE_LIVING){    // 人员在世，设置人员的账号、用户名、密码，不在世，则随意设置
            if(userDto.getUserAccount() == null){
                userDto.setUserAccount(userDto.getUserPhone());
            }
            if(userDto.getUserName() == null){
                userDto.setUserName(userDto.getUserPhone());
            }
            userDto.setUserPassword(userDto.getUserPhone().substring(userDto.getUserPhone().length()-6,userDto.getUserPhone().length()));
        }

        if(userDto.getActive() == null){
            userDto.setActive(1);
        }

        userDto.setUserCreateTime(new Date());
        Long result = userMapper.insertUserAgile(userDto);
        if(result <= 0){
            throw new BaseException("创建账户失败！");
        }
    }

    @Override
    public void updateUser(UserDto userDto) {
        if(userDto.getId() == null){
            throw new BaseException("修改失败！未传入唯一标识！");
        }
        Long result = userMapper.updateUser(userDto);
        if (result <= 0){
            throw new BaseException("没有该人员，无法修改信息！");
        }
    }

    @Override
    public void checkAccount(String account) {
        Long aLong = userMapper.checkPhone(account);
        if(aLong > 0){
            throw new BaseException("已被注册");
        }
    }

    @Override
    public void checkUser(UserDto userDto) {

        User user = userMapper.checkUserInfoByUser(userDto);
        if(user != null){

        }else {

//            userMapper.insertUser(userDto);
        }

    }

    @Override
    public User queryUserByPhone(String phone) {
        User user = userMapper.queryUserByPhone(phone);
        return user;
    }

    @Override
    public User queryUserById(Long userId) {
        User user = userMapper.queryUserById(userId);
        return user;
    }

    @Override
    public PageResponse<UserVo> queryUsers(PageRequest<UserDto> queryDto) {
        PageResponse<UserVo> pageResponse = new PageResponse<>();
        Integer pageIndex = Long.valueOf(queryDto.getOffset()).intValue();
        Integer pageSize = queryDto.getPageSize();

        UserDto userDto = new UserDto();

        Long count = userMapper.getCount(userDto);
        if(count > 0){

        }

        return null;
    }
}
